home *** CD-ROM | disk | FTP | other *** search
-
- /*
- File: QDLibrary.c
-
- Contains: graphics libraries - quickdraw conversion library
-
- Written by: Cary Clark, Georgiann Delaney, Michael Fairman, Dave Good, Robert Johnson, Keith McGreggor, Oliver Steele, David Van Brink, Chris Yerga
-
- Copyright: © 1995 by Apple Computer, Inc., all rights reserved.
-
- Change History (most recent first):
-
- <4> 5/4/95 JD cleaning out fixed and fract
- <3> 4/7/95 jtd taking out all references to 'GestaltEqu.h'
- <2> 1/9/95 JD changed 'boolean' to 'Boolean'
- <1> 1/9/95 JD First checked in.
- */
-
- #include <Errors.h>
- #include <Quickdraw.h>
- #include <Memory.h>
- #include <Resources.h>
- #include <Gestalt.h>
- #include "GraphicsLibraries.h"
- #include "OffscreenLibrary.h"
- #include "QDLibrary.h"
-
-
- gxRectangle *ShortRectToFixed(const Rect *shortRect, gxRectangle *fixedRect)
- {
- register Fixed *coord;
-
- NilParamReturnNil(shortRect);
- NilParamReturnNil(fixedRect);
- coord = (Fixed *) fixedRect;
- *coord++ = IntToFixed(shortRect->left);
- *coord++ = IntToFixed(shortRect->top);
- *coord++ = IntToFixed(shortRect->right);
- *coord = IntToFixed(shortRect->bottom);
- return fixedRect;
- }
-
-
- Rect *FixedRectToShort(const gxRectangle *fixedRect, Rect *shortRect)
- {
- register short *coord;
-
- NilParamReturnNil(shortRect);
- NilParamReturnNil(fixedRect);
- coord = (short *) shortRect;
- *coord++ = FixedRound(fixedRect->top);
- *coord++ = FixedRound(fixedRect->left);
- *coord++ = FixedRound(fixedRect->bottom);
- *coord = FixedRound(fixedRect->right);
- return shortRect;
- }
-
- gxPoint *ShortPointToFixed(const Point *shortPoint, gxPoint *fixedPoint)
- {
- NilParamReturnNil(shortPoint);
- NilParamReturnNil(fixedPoint);
- fixedPoint->x = IntToFixed(shortPoint->h);
- fixedPoint->y = IntToFixed(shortPoint->v);
- return fixedPoint;
- }
-
-
- Point *FixedPointToShort(const gxPoint *fixedPoint, Point *shortPoint)
- {
- NilParamReturnNil(shortPoint);
- NilParamReturnNil(fixedPoint);
- shortPoint->h = FixedRound(fixedPoint->x);
- shortPoint->v = FixedRound(fixedPoint->y);
- return shortPoint;
- }
-
- static gxColorSet CTabPtrToColorSet(const CTabPtr qdColors)
- {
- gxColorSet gnuSet;
-
- NilParamReturnNil(qdColors);
- { gxSetColor *tempColors, *colorPtr;
- unsigned short *qdSpec;
- short count, size;
-
- size = qdColors->ctSize + 1;
- tempColors = (gxSetColor *) NewPtr(size * sizeof(gxSetColor));
- NilParamReturnNil(tempColors);
- count = size;
- colorPtr = tempColors;
- qdSpec = (unsigned short *) &qdColors->ctTable;
- while (--count >= 0)
- {
- ++qdSpec;
- colorPtr->rgb.red = *qdSpec++;
- colorPtr->rgb.green = *qdSpec++;
- colorPtr->rgb.blue = *qdSpec++;
- ++colorPtr;
- }
- gnuSet = GXNewColorSet(gxRGBSpace, size, tempColors);
- DisposePtr((Ptr) tempColors);
- }
- return gnuSet;
- }
-
-
- gxColorSet CTableToColorSet(const CTabHandle qdColors)
- { char flags;
- gxColorSet gnuSet;
-
- NilParamReturnNil(qdColors);
- flags = HGetState((Handle)qdColors);
- HLock((Handle)qdColors);
- gnuSet = CTabPtrToColorSet(*qdColors);
- HSetState((Handle)qdColors,flags);
- return gnuSet;
- }
-
-
- CTabHandle ColorSetToCTable(const gxColorSet set)
- {
- long i,n,numbertocopy;
- CTabHandle mycolortable;
- gxSetColor * mycolorlist;
- gxColorSpace setSpace;
-
- NilColorSetReturnNil(set);
- n = GXGetColorSet(set, nil, nil);
- if (n < 4) numbertocopy = 2;
- else if (n < 16) numbertocopy = 4;
- else if (n < 256) numbertocopy = 16;
- else numbertocopy = 256;
- mycolorlist = (gxSetColor *)NewPtr(sizeof(gxSetColor)*numbertocopy);
- NilParamReturnNil(mycolorlist);
- mycolortable = (CTabHandle)NewHandle(sizeof(ColorTable)+numbertocopy*sizeof(ColorSpec));
- NilParamReturnNil(mycolortable);
- GXGetColorSet(set, &setSpace, mycolorlist );
- (*mycolortable)->ctSeed = 0;
- (*mycolortable)->ctFlags = 0;
- (*mycolortable)->ctSize = numbertocopy-1;
- for (i = 0; i < numbertocopy; i++)
- { gxColor tempcolor;
-
- tempcolor.element.rgba = mycolorlist[i].rgba;
- tempcolor.space = setSpace;
- tempcolor.profile = nil;
- if (setSpace != gxRGBSpace) GXConvertColor(&tempcolor,gxRGBSpace, nil, nil);
- (*mycolortable)->ctTable[i].value = 0;
- (*mycolortable)->ctTable[i].rgb.red = tempcolor.element.rgb.red;
- (*mycolortable)->ctTable[i].rgb.green = tempcolor.element.rgb.green;
- (*mycolortable)->ctTable[i].rgb.blue = tempcolor.element.rgb.blue;
- }
- return mycolortable;
- }
-
-
- /*** WARNING - this proc. should only be used with a rowBytes that is a multiple of four */
- /*** We should rev this to no longer have this restriction (by copying the gxBitmap, for example) */
- gxBitmap *ConvertFromQDBitmap(const BitMap *qdBits, gxBitmap *newBits)
- {
- NilParamReturnNil(qdBits);
- NilParamReturnNil(newBits);
- newBits->image = (char *) qdBits->baseAddr;
- newBits->rowBytes = qdBits->rowBytes;
- newBits->width = qdBits->bounds.right - qdBits->bounds.left;
- newBits->height = qdBits->bounds.bottom - qdBits->bounds.top;
- newBits->pixelSize = 1;
- newBits->space = gxIndexedSpace;
- newBits->set = nil;
- newBits->profile = nil;
- return newBits;
- }
-
- BitMap *ConvertToQDBitmap(const gxBitmap *newBits, BitMap *qdBits)
- {
- NilParamReturnNil(qdBits);
- NilParamReturnNil(newBits);
- qdBits->baseAddr = (Ptr) newBits->image;
- qdBits->rowBytes = newBits->rowBytes;
- SetRect(&qdBits->bounds, 0, 0, newBits->width, newBits->height);
- return qdBits;
- }
-
- gxShape BitMapToShape(const BitMap *srcBits)
- {
- gxBitmap newBits;
- gxShape bitmapShape;
-
- NilParamReturnNil(srcBits);
- bitmapShape = GXNewBitmap(ConvertFromQDBitmap(srcBits, &newBits), nil);
- return bitmapShape;
- }
-
- gxShape PixMapToShape(const PixMapHandle pmHandle)
- {
- gxShape bitsShape; /* the result gxShape */
- PixMap pixmaprecord; /* the header is read into here if we're using partial resources */
- PixMap *pixmap; /* points either into the resource or to the above record */
- gxBitmap srcBits;
- gxBitmap dstBits;
- register short srcRowBytes;
- char savedHandleFlags; /* so we can restore the handle state after we lock it */
- Boolean partialReads = false; /* are we using partial resources to read a bit at a time? */
-
- NilParamReturnNil(pmHandle);
- if (*pmHandle == nil) {
- #ifndef cpuNewton
- long systemVersion; /* filled out by Gestalt */
- OSErr err;
-
- /* The resource isn't loaded. Try to read it in all at once, since that's quite a bit faster,
- * but if that isn't possible because there isn't enough memory, use the partial resource
- * manager to read it in a bit at a time.
- */
- LoadResource((Handle) pmHandle);
- err = ResError();
- if (err == memFullErr && Gestalt(gestaltSystemVersion, &systemVersion) == noErr && systemVersion >= 1792) {
- partialReads = true;
- ReadPartialResource((Handle) pmHandle, 0, (Ptr) (pixmap = &pixmaprecord), sizeof(pixmaprecord));
- if ((err = ResError()) != 0) goto returnResError;
- } else if (err) {
- returnResError:
- GXPostGraphicsError(err);
- return nil;
- } else {
- (*pmHandle)->pmTable = nil;
- (*pmHandle)->baseAddr = nil;
- }
- #else
- DebugStr("PixMapToShape: no support for zero Handles");
- #endif
- }
-
- #ifdef cpuNewton
- (*pmHandle)->pmTable = nil;
- (*pmHandle)->baseAddr = nil;
- #endif
-
- savedHandleFlags = HGetState((Handle) pmHandle);
- HLock((Handle) pmHandle);
- if (partialReads == false)
- pixmap = *pmHandle;
- dstBits.space = gxIndexedSpace;
- dstBits.set = nil;
- dstBits.profile = nil;
- dstBits.pixelSize = pixmap->pixelSize;
- dstBits.width = pixmap->bounds.right - pixmap->bounds.left;
- dstBits.height = pixmap->bounds.bottom - pixmap->bounds.top;
- srcRowBytes = pixmap->rowBytes & 0x3FFF;
- dstBits.rowBytes = srcRowBytes;
- if (dstBits.pixelSize <= 8) {
- CTabHandle ctHandle;
-
- if (partialReads) {
- long resourceOffset = sizeof(PixMap) + srcRowBytes * dstBits.height;
- ColorTable cTable;
- CTabPtr ctPtr;
- long size;
-
- ReadPartialResource((Handle) pmHandle, resourceOffset, (Ptr) &cTable, sizeof(cTable));
- size = sizeof(ColorTable) - sizeof(CSpecArray) + cTable.ctSize * sizeof(CSpecArray);
- ctPtr = (CTabPtr) NewPtr(size);
- IfDebug(ctPtr == nil, "\pcouldn't allocate CTabPtr");
- ReadPartialResource((Handle) pmHandle, resourceOffset, (Ptr) ctPtr, size);
- dstBits.set = CTabPtrToColorSet(ctPtr);
- DisposePtr((Ptr) ctPtr);
- } else if ((ctHandle = pixmap->pmTable) != nil)
- dstBits.set = CTableToColorSet(ctHandle);
- else
- dstBits.set = CTabPtrToColorSet((CTabPtr) ((char *) pixmap + sizeof(PixMap) + srcRowBytes * dstBits.height));
- dstBits.space = gxIndexedSpace;
- } else if (dstBits.pixelSize == 16)
- dstBits.space = gxRGB16Space;
- else
- dstBits.space = gxRGB32Space;
- {
- long resourceOffset;
- gxShape pixShape;
- short scans;
- gxLongRectangle bounds;
-
- /* Decide how many scan lines to copy at once. If we use smaller chunks than the whole image,
- we never have to load the whole resource into memory, and the graphics system can offload
- pieces of it as they're written. Otherwise, the whole resource and the whole destination gxShape
- must be in memory at once. Enough lines to come in just under 32K seems like a reasonable number.
- */
- dstBits.image = nil;
- srcBits = dstBits;
- if (srcRowBytes & 3) { /* make it a long multiple */
- dstBits.rowBytes = srcRowBytes + 3 & ~3;
- scans = 1;
- } else if (partialReads)
- scans = 1;
- else {
- scans = 32768 / srcRowBytes;
- if (scans == 0)
- scans = 1;
- }
- if (scans > dstBits.height)
- scans = dstBits.height;
- srcBits.height = scans;
- if (partialReads) {
- resourceOffset = sizeof(PixMap);
- srcBits.image = (char *) NewPtr(srcBits.rowBytes);
- IfDebug(srcBits.image == nil, "\pcouldn't allocate rowBytes");
- } else if ((srcBits.image = (char *) pixmap->baseAddr) == nil)
- srcBits.image = (char *) pixmap + sizeof(PixMap);
- bitsShape = GXNewBitmap(&dstBits, nil);
- pixShape = GXNewBitmap(&dstBits, nil);
- bounds.left = bounds.top = 0;
- bounds.right = srcBits.width;
- bounds.bottom = scans;
- while (bounds.top < dstBits.height) {
- if (partialReads) {
- ReadPartialResource((Handle) pmHandle, resourceOffset, srcBits.image, srcBits.rowBytes);
- resourceOffset += srcBits.rowBytes;
- }
- GXSetBitmap(pixShape, &srcBits, nil);
- GXSetBitmapParts(bitsShape, &bounds, pixShape);
- bounds.top += scans;
- bounds.bottom += scans;
- if (bounds.bottom > dstBits.height)
- bounds.bottom = dstBits.height;
- if (partialReads == false)
- srcBits.image += scans * srcBits.rowBytes;
- }
- if (partialReads)
- DisposePtr((Ptr) srcBits.image);
- GXDisposeShape(pixShape);
- }
- HSetState((Handle) pmHandle, savedHandleFlags);
- if (dstBits.set)
- GXDisposeColorSet(dstBits.set);
- return bitsShape;
- }
-
-
- gxShape GetPixMapShape(short resourceID)
- {
- PixMapHandle pmHandle;
-
- SetResLoad(false);
- pmHandle = (PixMapHandle) GetResource('pxmp', resourceID);
- SetResLoad(true);
- if (pmHandle) {
- gxShape dest;
-
- dest = PixMapToShape(pmHandle);
- ReleaseResource((Handle)pmHandle);
- return dest;
- } else
- return nil;
- }
-
- #define kColorSpecSize 8
-
- gxShape CICNToMask(CIconHandle iconH)
- {
- CIconPtr iconP;
-
- NilParamReturnNil(iconH);
- iconP = *iconH;
- iconP->iconMask.baseAddr = (Ptr) &iconP->iconMaskData;
- return BitMapToShape(&iconP->iconMask);
- }
-
- gxShape CICNToShape(CIconHandle iconH)
- {
- NilParamReturnNil(iconH);
- { gxShape result = nil;
- CIconPtr iconP = *iconH;
- long height = iconP->iconPMap.bounds.bottom - iconP->iconPMap.bounds.top;
- ColorTable* clut = (ColorTable*) (((char*)&iconP->iconMaskData)
- + iconP->iconBMap.rowBytes*height
- + iconP->iconMask.rowBytes*height);
- long clutSize = 8+((clut->ctSize+1)*kColorSpecSize);
-
- PtrToHand((Ptr) clut, (Handle *) &iconP->iconPMap.pmTable, clutSize);
- iconP->iconPMap.baseAddr = (Ptr) (((char *)clut) + clutSize);
- result = PixMapToShape((PixMapHandle) iconH);
- DisposeHandle((Handle) iconP->iconPMap.pmTable);
- return result;
- }
- }
-
- gxShape GetCICNMask(long resourceID)
- {
- gxShape result = nil;
- CIconHandle iconH = (CIconHandle) GetResource('cicn', resourceID);
-
- if (iconH) {
- result = CICNToMask(iconH);
- ReleaseResource((Handle)iconH);
- }
- return result;
- }
-
- gxShape GetCICNShape(long resourceID)
- {
- gxShape result = nil;
- CIconHandle iconH = (CIconHandle) GetResource('cicn', resourceID);
-
- if (iconH) {
- result = CICNToShape(iconH);
- ReleaseResource((Handle)iconH);
- }
- return result;
- }
-